package com.feicheng.lanniao.controller.weChatNativePay.carSellInfo;

import com.alibaba.fastjson.JSONObject;
import com.feicheng.lanniao.controller.weChatNativePay.constant.WechatPayConfig;
import com.feicheng.lanniao.controller.weChatNativePay.pojo.CarRentalAndSellPcClientPOJO;
import com.feicheng.lanniao.entity.*;
import com.feicheng.lanniao.service.*;
import com.feicheng.lanniao.service.order.OrderService;
import com.feicheng.lanniao.util.AesUtil;
import com.feicheng.lanniao.util.JsonUtil;
import com.feicheng.lanniao.util.WechatPayUtils;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;


@RestController
@Slf4j
public class WeixinCarSellInfoNativeCallBack {

    @Autowired
    ICarSellInfoService iCarSellInfoService;
    @Autowired
    ICarSellClientVoService iCarSellClientVoService;
    @Autowired
    ICarService iCarService;
    @Autowired
    ICarSellOwnerService iCarSellOwnerService;
    @Autowired
    private OrderService orderService;

    @PostMapping("/result/carSellInfo")
    public Map  notifyWeixinPay(@RequestBody Map body, HttpServletRequest request) throws Exception {
        log.info("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
        log.info("WeixinCarSellInfoNativeCallBack的notifyWeixinPay方法进入");
        Map<String,Object> result = new HashMap<>();

        //获取微信支付回调的获取签名信息
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        log.info("timestamp为"+timestamp+",nonce为"+nonce);
        ObjectMapper objectMapper = new ObjectMapper();
        try{
            //2.开始解析报文体
            String data = objectMapper.writeValueAsString(body);
            log.info("data为:"+data);
            String message = timestamp + "\n" + nonce + "\n" + data + "\n";
            log.info("message为:"+message);
            //3.获取应答签名
            String sign = request.getHeader("Wechatpay-Signature");

            //获取平台对应的证书
            String serialNo = request.getHeader("Wechatpay-Serial");
            if (!WechatPayConfig.CERTIFICATE_MAP.containsKey(serialNo)) {
                WechatPayConfig.CERTIFICATE_MAP = WechatPayUtils.refreshCertificate();
            }

            X509Certificate x509Certificate = WechatPayConfig.CERTIFICATE_MAP.get(serialNo);
            if (!WechatPayUtils.verify(x509Certificate, message.getBytes(), sign)) {
                throw new IllegalArgumentException("微信支付签名验证失败:" + message);
            }
            log.info("签名验证成功");
            Map<String, String> resource = (Map) body.get("resource");
            // 5：回调报文解密
            AesUtil aesUtil = new AesUtil(WechatPayConfig.KEY.getBytes());

            //解密后json字符串
            String decryptToString = aesUtil.decryptToString(
                    resource.get("associated_data").getBytes(),
                    resource.get("nonce").getBytes(),
                    resource.get("ciphertext"));
            log.info("2------------->decryptToString====>{}",decryptToString);

            //6：获取微信支付返回的信息
            Map<String, Object> jsonData = objectMapper.readValue(decryptToString, Map.class);
            log.info("jsonData为"+jsonData);


            if ("SUCCESS".equals(jsonData.get("trade_state"))) {
                // 8：获取支付的交易单号，流水号，和附属参数
                String out_trade_no = jsonData.get("out_trade_no").toString();
                String transaction_id = jsonData.get("transaction_id").toString();
                String attach = jsonData.get("attach").toString();
                //TODO 根据订单号查询支付状态，如果未支付，更新支付状态 为已支付
                log.info("3----------->微信支付成功,支付流水号是：{},附属参数是：{}", out_trade_no,attach);
                log.info("4----------->微信支付成功,支付流水号是：{}", transaction_id);
                // 转换附属参数
                HashMap<String,Object> map = JsonUtil.string2Obj(attach,HashMap.class);
                log.info("map为"+map);
                //TODO 在这里做逻辑判断,判断发布类型,进而插入相对于的表  lanniao
                log.info("attach="+jsonData.get("attach").toString());
                String  carSellInfoPOJOJson =
                        (String) jsonData.get("attach");

                log.info("carSellInfoPOJOJson =>=>=>=>=>"+carSellInfoPOJOJson);
                CarRentalAndSellPcClientPOJO carSellInfoPOJO =
                        JSONObject.parseObject(carSellInfoPOJOJson, CarRentalAndSellPcClientPOJO.class);


                Car car = new Car();
                car.setCarCondition(carSellInfoPOJO.getCarCondition());
                car.setMileage(carSellInfoPOJO.getMileage());
                car.setBrandId(carSellInfoPOJO.getBrandId());
                car.setType(carSellInfoPOJO.getType());
                car.setCarBuyTime(carSellInfoPOJO.getCarBuyTime());
                iCarService.addCarInfo(car);

                //创建CarSellInfo对象
                CarSellInfo carSellInfo = new CarSellInfo();
                carSellInfo.setCarId(car.getCarId());
                carSellInfo.setSellPrice(car.getSellPrice());
                iCarSellInfoService.save(carSellInfo);
                //创建中间表对象
                CarSellOwner carSellOwner = new CarSellOwner();
                carSellOwner.setClientId(carSellInfoPOJO.getClientId());
                carSellOwner.setCarSellInfoId(carSellInfo.getCarSellInfoId());
                iCarSellOwnerService.save(carSellOwner);


                //插入订单信息
                Map amountMap = (HashMap)jsonData.get("amount");
                log.info("amountJson为"+amountMap);
                Integer total =(Integer) amountMap.get("total");
                log.info("total为====>"+total);

                //添加一条订单信息
                orderService.insertOrder(carSellInfoPOJO.getClientId(),total,"买车发布订单");

            }
            result.put("code", "SUCCESS");
            result.put("message", "成功");
        }catch (Exception e){
            result.put("code", "fail");
            result.put("message", "系统错误");
            e.printStackTrace();
        }

        return result;
    }
}
